﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"QDebug"
#include <QDateTime>
#include <QDir>
#include <QGuiApplication>
#include <QImageReader>
#include <QSettings>
#include "Utils.h"
#include <QMessageBox>
#include <QScreen>
#include<QDesktopServices>
#include<QProcess>
#define console_only 1
MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  ui->label_3->setPixmap(QPixmap::fromImage(QImageReader(":/qss/myicon/logo2x.png").read()));

//  cv::Mat frame = cv::imread("111.jpg");
//  cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
//  widgetReszImg->setImg(frame);

  ui->verticalLayout_8->addWidget(widgetReszImg);
  LoadConfig();

  camera= new CameraCtrl();
  ////  camera= new CameraCtrl(ip1,ip2,ip3,ip4);

  emit ui->SpinBox_Exposure->editingFinished();
  emit ui->SpinBox_gain->editingFinished();

  move_stage = new MoveStage(port);
  std::cout<<"move_stage connect:"<<move_stage->isConnect()<<"\n";


  cycle_move_worker->moveToThread(cycle_move_thread);
  ui->label_Exposure->setText(QString::number(camera->getExposureTime()));
  ui->label_gain->setText(QString::number(camera->getGain()));

  camera->startAcquirsition();
  camera->registerCaptureCallback([this](cv::Mat mat) {
    //图片产生太快 无法及时消费时 就不向list里面放入新图片
    if (image_show_list_.size() < 3) {
      image_show_list_.push_back(mat);
      emit getImage();
    }else{
      std::cout<<"image_show_list_.size() > 3 !!!! \n";
    }
    //只有上一次结束后才开始下一次
    if (!cycle_move_thread->isRunning() && times /*&& move_finish */&& !move_error) {
      image_move_save_list_.push_back(mat.clone());
      cycle_move_thread->start();
    }
  });
  connect(this, &MainWindow::getImage, this, [this]() {
    if (image_show_list_.empty()) {
      return;
    }
    cv::Mat mat = image_show_list_.front();
    image_show_list_.pop_front();
    widgetReszImg->setImg(mat);
  });


  connect(move_stage->serial,&QSerialPort::readyRead, this, [=]{
    mutex_com.lock();
    QByteArray buffer = move_stage->serial->readAll();
    mutex_com.unlock();
    //      std::cout<<"------read------: \n";
    //      std::cout<<"respone size"<<buffer.size()<<std::endl;
    if(buffer.size()>10){
      qDebug()<<"respone size "<<buffer.size()<< ">10  quit move!!!";
      move_finish = true;
      move_error = true;
    }
    //      for (int i = 0;i<buffer.size() ;i++){
    //        printf("  %x   ", buffer.data()[i]&0xff);
    //      }
    //      printf("\n");

    if (byte10.size()<10){
      byte10.append(buffer);
      //        qDebug()<<"byte10.size()"<<byte10.size();
      if(byte10.size()>10){
        qDebug()<<"byte10 size "<<byte10.size()<< ">10  !!!!!";
        //          byte10.resize(10);
        move_finish = true;
        move_error = true;
      }
    }else if(byte10.size()==10){
      byte10.clear();
      byte10.append(buffer);
      //        qDebug()<<"byte10.size()"<<byte10.size();
    }

    if(byte10.size()==10){
      std::cout<<"------byte10.size ==10 ------: \n";
      printf("byte10");printf("\n");
      for (int i = 0;i<byte10.size() ;i++){
        printf("  %x   ", byte10.data()[i]&0xff);
      }
      printf("\n");
      mutex_movefinish.lock();
      if(!isbreak)
        isMoveFinsih(byte10,move_finish,move_error);
      mutex_movefinish.unlock();
      qDebug()<<"move_finish"<<move_finish;
      if(move_error){
        ui->is_error->setText("error!!!");
      }
    }
    /* printf("\n"); printf("\n");*/ /*printf("\n");*/

  });

  connect(cycle_move_thread, &QThread::started, cycle_move_worker, [this]() {

    if (image_move_save_list_.empty()) {
      cycle_move_thread->quit();
    }
    cv::Mat mat = image_move_save_list_.front();
    image_move_save_list_.pop_front();
    //多线程
    mutex_movefinish.lock();
    move_finish = false;
    mutex_movefinish.unlock();
    start_D_S_P_G();
    if(ui->checkBox_autosave->isChecked()){
      QString save_path = save_dir;
      std ::string name = save_path.append("/").append(QString::number(total_times - times+1)).append(".png").toStdString();
      std::cout<<name<<std::endl;
      std::cout<<"save success ?: "<<cv::imwrite(name,mat.clone())<<"\n";
    }

    ////移动完成后延迟一会儿再存图片 image_move_save_list_ 放入新图片
    while(!move_finish){
      QThread::msleep(20);
    }
    if(times!=1)//最后一次不延时
      QThread::msleep(ui->spinBox_delay->value());
    mutex_times.lock();
    times --;
    mutex_times.unlock();
    ui->current_time->setText(QString("finish:").append(QString::number(total_times - times)));
    std::cout<<"========move finish times:========== "<<total_times - times<<"  /  "<<total_times <<"\n";
    cycle_move_thread->quit();

  });
#if !console_only
  if(!camera->getIs_connect()){
    QMessageBox::critical(NULL, QString::fromLocal8Bit("提示!!!!!"),
                          QString::fromLocal8Bit("相机未连接"),
                          QMessageBox::Yes);
  }

  if(!move_stage->isConnect()){
    QMessageBox::critical(NULL, QString::fromLocal8Bit("提示!!!!!"),
                          QString::fromLocal8Bit("平移台未连接"),
                          QMessageBox::Yes);
  }
  this->setWindowFlags(Qt::WindowTitleHint);
  this->show();
#endif
#if console_only
    emit ui->pushButton_go->clicked();
#endif

}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::on_close_clicked()
{
  //如果点击确认
  int ret = QMessageBox::Yes;
  ret = QMessageBox::critical(NULL, QString::fromLocal8Bit("提示!!!!!"),
                              QString::fromLocal8Bit("是否要关闭软件"),
                              QMessageBox::Yes , QMessageBox::Cancel);
  if(QMessageBox::Yes == ret){
    saveConfig();
    this->close();
  }

}
void MainWindow::on_min_clicked()
{
  this->showMinimized();
}


void MainWindow::start_D_S_P_G()
{
  std::cout<<"=========D_S_P_G  start write =======================\n";
  mutex_com.lock();
  move_stage->setLR((unsigned int)ui->radioButton_l->isChecked());
  mutex_com.unlock();
  _sleep(20);

  mutex_com.lock();
  move_stage->setSpeed((unsigned int )ui->spinBox_speed->value());
  mutex_com.unlock();
  _sleep(20);

  //mutex.lock();
  move_stage->setDistance((unsigned int)ui->spinBox_step->value());
  //mutex.unlock();
  _sleep(20);

  mutex_com.lock();
  move_stage->lanchGo();
  mutex_com.unlock();
  std::cout<<"=========D_S_P_G write finish=======================\n\n";
}

void MainWindow::LoadConfig()
{
  QSettings settings("./Settings.conf", QSettings::IniFormat);
  port = settings.value("COM","COM3").toString();
  settings.value("direction",1).toUInt();
  ui->radioButton_l->setChecked(settings.value("direction",1).toUInt());
  ui->radioButton_r->setChecked( !ui->radioButton_l->isChecked());

  ui->spinBox_step->setValue(settings.value("step",200).toDouble());
  ui->spinBox_speed->setValue(settings.value("speed",10).toUInt());
  ui->spinBox_times->setValue(settings.value("times",10).toUInt());
  ui->spinBox_delay->setValue(settings.value("delay",0).toUInt());
  ui->checkBox_autosave->setChecked(settings.value("auto_save",false).toBool());

  ui->SpinBox_Exposure->setValue(settings.value("exposure",5500).toDouble());

  ui->SpinBox_gain->setValue(settings.value("gain",0).toDouble());

  ip1 = settings.value("ip1",192).toUInt();
  ip2 = settings.value("ip2",192).toUInt();
  ip3 = settings.value("ip3",192).toUInt();
  ip4 = settings.value("ip4",192).toUInt();

}

void MainWindow::saveConfig()
{
  QSettings settings("./Settings.conf", QSettings::IniFormat);
  settings.setValue("COM",move_stage->GetPortName());
  settings.setValue("direction", ui->radioButton_l->isChecked());
  settings.setValue("step",  ui->spinBox_step->value());
  settings.setValue("speed",  ui->spinBox_speed->value());
  settings.setValue("times",  ui->spinBox_times->value());
  settings.setValue("delay",  ui->spinBox_delay->value());
  settings.setValue("auto_save",   ui->checkBox_autosave->isChecked());
  settings.setValue("ip",  camera->getIP());
  settings.setValue("exposure",  ui->SpinBox_Exposure->value());
  settings.setValue("ip1",  ip1);
  settings.setValue("ip2",  ip2);
  settings.setValue("ip3",  ip3);
  settings.setValue("ip4",  ip4);
}



void MainWindow::on_pushButton_clicked()
{
  camera->stopAcquisition();
}

void MainWindow::on_SpinBox_Exposure_editingFinished()
{
  camera->setExposureTime(ui->SpinBox_Exposure->value());
  ui->label_Exposure->setText(QString::number(camera->getExposureTime()));
}

void MainWindow::on_SpinBox_gain_editingFinished()
{
  camera->setGain(ui->SpinBox_gain->value());
  ui->label_gain->setText(QString::number(camera->getGain()));
}



void MainWindow::on_pushButton_start_clicked()
{
  camera->startAcquirsition();
}
void MainWindow::on_pushButton_go_clicked()
{
  QDir folder =  QDir();
  QString path = QString("./batchs/");
  if(!folder.exists(path)){
    if(!folder.mkdir(QString(path))){
      qDebug()<<"mkdir fail";
      return ;
    }
  }
  if(ui->checkBox_autosave->isChecked()){
    save_dir = path.append(QDateTime::currentDateTime().toString("yyyyMMddhhmmssz"));
    if(!folder.exists(save_dir)){
      if(!folder.mkdir(QString(path))){
        qDebug()<<"mkdir fail";
        return ;
      }
    }
  }
#if console_only
  ui->pushButton_open_folder->clicked();
#endif
  isbreak = false;
  byte10.clear();
  ui->current_time->clear();
  ui->is_error->setText(QString::fromLocal8Bit("已完成轮次:"));
  times= ui->spinBox_times->value();
  total_times = times;
  move_error =false;
}
void MainWindow::on_pushButton_break_clicked()
{
  isbreak = true;
  mutex_movefinish.lock();
  move_error = 1;
  move_finish = 1;
  mutex_movefinish.unlock();

}
void MainWindow::on_pushButton_open_folder_clicked()
{
  QProcess::startDetached("explorer " + (QDir::toNativeSeparators(save_dir)) );
}
